--==============================================================================
-- MailMod - ver 1.0
-- 日期: 2007-12-5
-- 作者: 独孤傲雪
-- 描述: 提供一系列的邮件辅助功能, 例如记录收件人名字和批量收取邮件等
-- 版权所有: 艾泽拉斯国家地理
-- 特别鸣谢: 原CT_MailMod. 由于2.3邮件系统的改变, 原CT_MailMod已无法使用. 现在单体
--			 的CT_MailMod具有版权, 我们在未取得授权的情况下不得进行修改, 所以我们重
--			 写了该插件. 
--														-- 大脚(BigFoot)开发团队. 
--==============================================================================
local L = BLocal("MailMod");
local MailMod_Hook = BLibrary("BHook");
local MailMod_Event = BLibrary("BEvent");

if (GetLocale() == "zhCN") then
	L["MailMod"] = "邮件助手";
	MAILMOD_OPEN_SELECT = "打开选择邮件";
	MAILMOD_OPEN_ALL = "打开所有邮件";
	MAILMOD_DISPLAY_PROCESS = "显示具体处理过程";
	L["Open All?"] = "确认打开邮件";
	L["Are you sure you want to open all mails?"]  = "你确定要打开所有邮件?";
	L["Display process messages"] = "显示邮件处理过程";
	L["Mail %d: %s |r is Cash on Delivery, skipping."] = "邮件 %d: %s 是付款取信邮件, 跳过...";
	L["Mail %d: %s has no money or items, skipping."] = "邮件%d: %s 没有金钱或物品, 跳过...";
	L["Opening mail %d: %s from %s."] = "正在打开邮件%d: %s, 来至%s.";
	L["Error: Inventory full. Aborting."] = "错误: 背包已满, 异常中断...";
	L["Click to select mail receiver"] = "点击选择收件人";	
	L["|cffff0000Warning: the contact list is full.|r"] = "|cffff0000警告:收件人列表已满|r";		
	L["Add to contact list"] = " 添加到收件人列表";
	L["Remove from contact list"] = "从收件人列表中移除";
	L["|cff00ff00Add|r %s)"] = "|cff00ff00添加|r %s";
	L["|cffff0000Remove|r %s)"] = "|cffff0000移除|r %s";
	L["Remember name of receiver"] = "记住收件人的名字";	
	L["<MailMod> %s."] = "<邮件助手> %s。";	
elseif (GetLocale() == "zhTW") then
	L["MailMod"] = "郵件助手";
	MAILMOD_OPEN_SELECT = "打開選擇郵件";
	MAILMOD_OPEN_ALL = "打開所有郵件";
	MAILMOD_DISPLAY_PROCESS = "顯示具體處理過程";
	L["Open All?"] = "確認打開郵件";	
	L["Are you sure you want to open all mails?"] = "你確定要打開所有郵件?";
	L["Display process messages"] = "顯示郵件處理過程";
	L["Mail %d: %s is Cash on Delivery, skipping."] = "郵件 %d: %s 是付款取信郵件, 跳過...";
	L["Mail %d: %s has no money or items, skipping."] = "郵件%d:%s 沒有金錢或物品, 跳過...";
	L["Opening mail %d: %s from %s."] = "正在打開郵件%d: %s, 來至%s.";
	L["Error: Inventory full. Aborting."] = "錯誤: 背包已滿, 異常中斷...";
	L["Click to select mail receiver"] = "點擊選擇收件人";		
	L["|cffff0000Warning: the contact list is full.|r"]	= "|cffff0000警告:收件人列表已滿|r";
	L["Add to contact list"] = " 添加到收件人列表";
	L["Remove from contact list"] = "從收件人列表中移除";
	L["|cff00ff00Add|r %s)"] = "|cff00ff00添加|r %s)";
	L["|cffff0000Remove|r %s)"]	= "|cffff0000移除|r %s)";	
	L["Remember name of receiver"] = "記住收件人的名字";
	L["<MailMod> %s."] = "<郵件助手> %s。";
else
	MAILMOD_OPEN_SELECT = "Open Select";
	MAILMOD_OPEN_ALL = "Open All";
	MAILMOD_DISPLAY_PROCESS = "Display process message";
end

local M = BLibrary("BInfo", "chat", L["MailMod"]);

MAILMOD_LIST_MAX_NUM = 30;
MailMod_Config = {
	["DisplayMessages"] = nil,
	["ContactList"] = {};
	--["Sendee"] = nil,
};
local EnableRightClick = false;
local MailMod_Enable = false;
local MailMod_Hooked = false;
local MailMod_Info = {["num"] = nil, ["numMails"] = nil, ["id"] = {},};
local MailMod_SelectedItems = {};
--------------------
-- 确认收取所有邮件
--------------------
-- StaticPopup_Show
StaticPopupDialogs["OPEN_ALL_MAILS"] = {
	text = L["Are you sure you want to open all mails?"],
	button1 = OKAY,
	button2 = CANCEL,
	OnAccept = function()
		MailMod_OpenSelected(1);
	end,	
	showAlert = 1,
	timeout = 0,
	exclusive = 1,
	hideOnEscape = 1,
};
--------------------
-- 在批量收取邮件期间阻止用户手动收取
--------------------
function MailMod_DisableClicks(disable, loopPrevention)
	if ( disable ) then
		for i = 1, 7, 1 do
			getglobal("MailItem" .. i .. "ButtonIcon"):SetDesaturated(1);
			getglobal("MailItem" .. i .. "Button"):Disable();
		end		
	else
		for i = 1, 7, 1 do
			getglobal("MailItem" .. i .. "ButtonIcon"):SetDesaturated(nil);
			getglobal("MailItem" .. i .. "Button"):Enable();
		end
		if ( not loopPrevention ) then	-- 阻止循环调用
			InboxFrame_Update();
		end
	end
end
--------------------
-- 判断是否可以删除该邮件
--------------------
local function canDelete(index)
	local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, itemID, wasRead, wasReturned, textCreated = GetInboxHeaderInfo(index);
	if ( money == 0 and not itemID and not textCreated) then
		return true;
	end
	return false;
end
--------------------
-- 批量打开邮件
--------------------
function MailMod_MassOpen(n)
	if (not MailMod_Info.num or (n and n <= 0)) then return end

	local n = n or MailMod_Info.num;
	local ID = MailMod_Info.id;
	if (n and n > 0) then
		table.sort(ID);
		for i=n, 1, -1 do			
			if (MailMod_Info.num) then
				local success = MailMod_PickMail(ID[i]);
				if (success>0 and canDelete(ID[i])) then
					GetInboxText(ID[i]);
					DeleteInboxItem(ID[i]);
				elseif (success and success == 2) then
					BigFoot_DelayCall(MailMod_MassOpen, 0.5, i);
					return;
				end
			else
				MailMod_DisableClicks(nil);
				return;
			end
		end
		MailMod_Info.num = nil;
		MailMod_Info.id = {};
		MailMod_DisableClicks(nil);
	end
	MailMod_Info.inboxChecked = true
	CheckInbox()
end
--------------------
-- 异常中断
--------------------
function MailMod_Abort()
	MailMod_Info.num = nil;
	MailMod_Info.numMails = nil;
	MailMod_Info.id = {};
	MailMod_SelectedItems = {};
	MailMod_DisableClicks();
end

function MailMod_Event.UI_ERROR_MESSAGE(msg)
	if (msg == ERR_INV_FULL or msg == ERR_ITEM_MAX_COUNT ) then
		if ( MailMod_Info.num ) then
			if ( msg == ERR_INV_FULL ) then
				MailMod_Abort();
				if ( MailMod_Config.DisplayMessages ) then
					M:Print(L["Error: Inventory full. Aborting."]);
				end
			elseif ( msg == ERR_ITEM_MAX_COUNT ) then
				if ( MailMod_Config.DisplayMessages ) then
					M:Print(L["Error: You already have the maximum amount of that item. Aborting."]);
				end				
				MailMod_Abort();				
			end
		end
	end
end

function MailMod_Event.MAIL_INBOX_UPDATE()
	if MailMod_Info.inboxChecked then
		local __num_items=GetInboxNumItems()
		if __num_items==0 then 
			MiniMapMailFrame:Hide()
		else
			
			for i=1,__num_items,1 do
				local _,_,_,_,_,_,_,_,__wasread=GetInboxHeaderInfo(i);
				if not __wasread then MiniMapMailFrame:Show() return end
			end
			MiniMapMailFrame:Hide()
		end
	end
end

function MailMod_PickMail(id)
	if ( not id ) then		
		return 0;
	end
	local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, itemCount, wasRead, wasReturned, textCreated, canReply = GetInboxHeaderInfo(id);
	if ( CODAmount > 0 ) then
		if ( MailMod_Config.DisplayMessages ) then
			M:Print(format(L["Mail %d: %s is Cash on Delivery, skipping."], id, subject or "<No Subject>"));
		end
		return 0;
	elseif ( not itemCount and money == 0) then
		if ( MailMod_Config.DisplayMessages ) then
			M:Print(format(L["Mail %d: %s has no money or items, skipping."], id, subject or "<No Subject>"));
		end
		return 0;
	end
	if ( MailMod_Config.DisplayMessages ) then
		M:Print(format(L["Opening mail %d: %s from %s."], id, subject or "<No Subject>", sender or "<Unknown Sender>"));
	end
	local hasMoneyorItem;
	if ( money > 0 ) then
		TakeInboxMoney(id);
		hasMoneyorItem = 1;
	end
	if ( itemCount and itemCount > 0) then		
		for i=1, ATTACHMENTS_MAX_RECEIVE do
			if (GetInboxItem(id, i)) then
				TakeInboxItem(id, i);
			end
		end
		hasMoneyorItem = 1;		
	end	

	if ( hasMoneyorItem ) then		
		return 2;
	else
		return 1;
	end	
end
--------------------
-- 设置选择打开的邮件
--------------------
function MailMod_SetSelected(self)
	local id = self:GetID() + (InboxFrame.pageNum-1)*7;
	if ( not self:GetChecked() ) then
		for k, v in pairs(MailMod_SelectedItems) do
			if ( v == id ) then
				tremove(MailMod_SelectedItems, k);
				break;
			end
		end
	else
		tinsert(MailMod_SelectedItems, id);
	end
end
--------------------
-- 批量打开邮件
--------------------
function MailMod_OpenSelected(openAll)
	MailMod_DisableClicks(1);
	MailMod_Info.num = 0;
	MailMod_Info.id = {};
	if ( openAll ) then		-- 全部打开邮件
		for i = 1, GetInboxNumItems(), 1 do
			MailMod_Info.num = MailMod_Info.num + 1;
			tinsert(MailMod_Info.id, i);
		end
	else
		for k, v in pairs(MailMod_SelectedItems) do
			MailMod_Info.num = MailMod_Info.num + 1;
			tinsert(MailMod_Info.id, v);
		end
	end
	MailMod_SelectedItems = {};
	MailMod_Info.numMails = MailMod_Info.num;
	MailMod_MassOpen();

end
--------------------
-- Hook InboxFrame_Update
--------------------
function MailMod_FrameUpdate(...)	
	if (MailMod_Enable) then
		for i = 1, 7, 1 do
			local index = (i + (InboxFrame.pageNum-1)*7);
			if ( index > GetInboxNumItems() ) then
				getglobal("MailBoxItem" .. i .. "CB"):Hide();
			else
				getglobal("MailBoxItem" .. i .. "CB"):Show();
				getglobal("MailBoxItem" .. i .. "CB"):SetChecked(nil);
				for k, v in pairs(MailMod_SelectedItems) do
					if ( v == index ) then
						getglobal("MailBoxItem" .. i .. "CB"):SetChecked(1);
						break;
					end
				end
			end
		end
		if ( MailMod_Info.num ) then
			MailMod_DisableClicks(1, 1);
		end
	end
end
--------------------
-- 关闭邮箱时执行异常中断
--------------------
local function MailMod_CloseMail(...)	
	if (MailMod_Enable) then
		MailMod_Abort();
	end	
end

function MailMod_DisplayMessagesCB_OnClick(self, button)
	MailMod_Config["DisplayMessages"] = self:GetChecked();
end
--==================
-- 增强鼠标提示信息
--==================
local function MailMod_FrameItem_OnEnter(self)
	if (MailMod_Enable) then
		local name, itemTexture, count, quality, canUse;
		if ( self.hasItem and self.itemCount > 1) then		
			for i=1, ATTACHMENTS_MAX_RECEIVE do
				name, itemTexture, count, quality, canUse = GetInboxItem(self.index, i);
				if (name) then
					GameTooltip:AddLine(format("%s |cff00ff00x%d|r", GetInboxItemLink(self.index, i), count));		
				end
			end
			GameTooltip:Show();
		end
	end
end
--==================
-- 快速添加邮寄物品
--==================
local function ItemButtonPostClick(self, button)	
	if (MailMod_Enable and IsAltKeyDown() and button == "LeftButton") then
		local bag, slot = self:GetParent():GetID(), self:GetID();
		if (bag and slot and SendMailFrame:IsShown()) then
			PickupContainerItem(bag, slot);
			if (CursorHasItem()) then
				for i=1, ATTACHMENTS_MAX_SEND do
					if (not GetSendMailItem(i)) then
						ClickSendMailItemButton(i);
					end
				end
			end
		end		
	end
end

local Server, Player, CurrentName, SelectName;

function MailModList_Init()
	Player = UnitName("player");
	Server = GetCVar("realmName");

	MailMod_Config["ContactList"][Server] = MailMod_Config["ContactList"][Server] or {};
	--CurrentName = MailMod_Config["Sendee"];
end
--------------------
-- 鼠标进入
--------------------
function MailModList_ButtonOnEnter(self)
	if (MailMod_Enable) then
		GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT");
		GameTooltip:SetText(self.tooltip);
	end
end
--------------------
-- 
--------------------
function MailModList_DropDown_OnShown(self) 	
	self.tooltip = L["Click to select mail receiver"];
	BDropDownMenu_Initialize(self:GetParent(), MailModList_DropDown_Init);
	BDropDownMenu_SetAnchor(self:GetParent(), 0, 0, "TOPRIGHT", self:GetName(), "BOTTOMRIGHT")
end

function MailModList_DropDown_Init(self)
	local info = {value = 0, notCheckable = 1};	
	CurrentName = SendMailNameEditBox:GetText();	
	if(CurrentName ~= "") then
		SelectName = MailModList_InList(CurrentName);
		if(SelectName) then
			info.text = string.format(L["|cffff0000Remove|r %s)"], CurrentName);
			info.func = MailModList_Remove;
		elseif(#(MailMod_Config["ContactList"][Server]) < MAILMOD_LIST_MAX_NUM) then
			info.text = string.format(L["|cff00ff00Add|r %s)"], CurrentName);
			info.func = MailModList_Add;
		else
			info = nil;
			M:Print(L["|cffff0000Warning: the contact list is full.|r"]);
		end
		if(info) then 
			BDropDownMenu_AddButton(info); 
		end
	end
	-- 人物列表
	for key, name in pairs(MailMod_Config["ContactList"][Server]) do
		info = {text=name, value=key, func=MailModList_Select};
		if(key == SelectName) then
			info.checked = 1;
		end
		BDropDownMenu_AddButton(info);
	end
end
--------------------
-- 选择收件人
--------------------
function MailModList_Select(self)
	local value = self.value;
	if(value) then
		CurrentName = MailMod_Config["ContactList"][Server][value];	
		SendMailNameEditBox:SetText(CurrentName);
		SendMailNameEditBox:HighlightText(0,-1);
	end
end
--------------------
-- 添加收件人
--------------------
function MailModList_Add()
	table.insert(MailMod_Config["ContactList"][Server], CurrentName);
	table.sort(MailMod_Config["ContactList"][Server]);
	MailToName_SavedName = SendMailNameEditBox:GetText();
	M:Print(CurrentName..L["Add to contact list"]);
end
--------------------
-- 取消收件人
--------------------
function MailModList_Remove()
	table.remove(MailMod_Config["ContactList"][Server], SelectName);	
	SendMailNameEditBox:SetText('');
	M:Print(CurrentName..L["Remove from contact list"]);
end
-------------------
-- 列表中是否有该名字
-------------------
function MailModList_InList(MCname)
	local LCname = string.lower(MCname);
	for key, name in pairs(MailMod_Config["ContactList"][Server]) do
		if(LCname == string.lower(name)) then 
			return key; 
		end
	end
end
--------------------------------------------------------------------------------
-- 
--------------------------------------------------------------------------------
local function MailMod_SecureHook()
	hooksecurefunc("InboxFrame_Update", MailMod_FrameUpdate);
	hooksecurefunc("CloseMail", MailMod_CloseMail);
	hooksecurefunc("InboxFrameItem_OnEnter", MailMod_FrameItem_OnEnter);
	hooksecurefunc("ContainerFrameItemButton_OnModifiedClick", ItemButtonPostClick);	
end

MailMod_Event:Init{
	name = "MailMod",
	func = function ()
		MailModList_Init();
		MailItem1:SetPoint("TOPLEFT", "InboxFrame", "TOPLEFT", 48, -80);
		for i = 1, 7, 1 do
			getglobal("MailItem" .. i .. "ExpireTime"):SetPoint("TOPRIGHT", "MailItem" .. i, "TOPRIGHT", 10, -4);
			getglobal("MailItem" .. i):SetWidth(280);
		end
		MailMod_InboxDisplayMessagesCB:SetChecked(MailMod_Config.DisplayMessages);	
	end
};

function MailMod_Toggle(switch)
	if (switch) then
		MailMod_Enable = true;
		if (not MailMod_Hooked) then
			MailMod_SecureHook();
		end
		MailMod_Event:RegisterEvent("UI_ERROR_MESSAGE");	
		MailMod_Event:RegisterEvent("MAIL_INBOX_UPDATE");
		MailMod_InboxOpenSelected:Show();
		MailMod_InboxOpenAll:Show();
		MailMod_InboxDisplayMessagesCB:Show();
		MailModList_DropDownMenuButton:Show();
		MailMod_Hooked = true;
	else
		MailMod_Enable = false;	
		MailMod_Event:UnregisterEvent("UI_ERROR_MESSAGE");		
		MailMod_Event:UnregisterEvent("MAIL_INBOX_UPDATE");
		MailMod_InboxOpenSelected:Hide();
		MailMod_InboxOpenAll:Hide();
		MailMod_InboxDisplayMessagesCB:Hide();
		MailModList_DropDownMenuButton:Hide();
	end
end